package pers.jphoebe.quartz.service.impl;

import com.sun.imageio.plugins.gif.GIFStreamMetadata;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import pers.jphoebe.quartz.api.juhe.GoldApi;
import pers.jphoebe.quartz.dao.mysql.GoldPriceMapper;
import pers.jphoebe.quartz.dao.mysql.SilverPriceMapper;
import pers.jphoebe.quartz.dao.mysql.VarietyMapper;
import pers.jphoebe.quartz.entity.*;
import pers.jphoebe.quartz.entity.juhe.GoldData;
import pers.jphoebe.quartz.entity.juhe.GoldDataMap;
import pers.jphoebe.quartz.entity.juhe.JuheResponse;
import pers.jphoebe.quartz.entity.juhe.VarietyType;
import pers.jphoebe.quartz.entity.response.ErrorCode;
import pers.jphoebe.quartz.entity.response.ResponseData;
import pers.jphoebe.quartz.exception.CustomException;
import pers.jphoebe.quartz.service.GoldDataFromJuheService;
import pers.jphoebe.quartz.utils.BigDecimalUtil;
import pers.jphoebe.quartz.utils.IdUtil;

import java.math.BigDecimal;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Created by 蒋时华 on 2017/11/1.
 */
@Service
public class GoldDataFromJuheServiceImpl implements GoldDataFromJuheService {

    @Autowired
    private GoldApi goldApi;
    @Autowired
    private GoldPriceMapper goldPriceMapper;
    @Autowired
    private SilverPriceMapper silverPriceMapper;
    @Autowired
    private VarietyMapper varietyMapper;

    private JuheResponse<ArrayList<GoldDataMap>> getDataByShgold() throws CustomException{
        ResponseData<JuheResponse<ArrayList<GoldDataMap>>> dataByShgold = goldApi.getDataByShgold();
        if(ErrorCode.SUCCESS_CODE.getCode().equals(dataByShgold.getCode())){
            return dataByShgold.getData();
        }
        throw new CustomException(dataByShgold.errorCode());
    }

    private GoldPrice goldDataToGoldPrice(GoldData goldData) throws CustomException{
        GoldPrice goldPrice = new GoldPrice();

        goldPrice.setId(IdUtil.getId());
        Variety variety;
        try{
            variety = this.getVarietyByName(goldData.getVariety());
            if(variety==null){
                throw new CustomException(ErrorCode.ERROR_RECEIVE_AUTD);
            }
        }catch (CustomException e){
            throw e;
        }
        goldPrice.setVarietyId(variety.getId());
        goldPrice.setLatestPrice(new BigDecimal(goldData.getLatestpri()));
        goldPrice.setOpenPrice(new BigDecimal(goldData.getOpenpri()));
        goldPrice.setMaxPrice(new BigDecimal(goldData.getMaxpri()));
        goldPrice.setMinPrice(new BigDecimal(goldData.getMinpri()));
        goldPrice.setYesterdayPrice(new BigDecimal(goldData.getYespri()));
        goldPrice.setTotalVolume(new BigDecimal(goldData.getTotalvol()));
        goldPrice.setTime(goldData.getTime());
        goldPrice.setLatestPriceTime(this.getCurrentTime());
        goldPrice.setCreateDate(new Timestamp(System.currentTimeMillis()));
        goldPrice.setUpdateDate(new Timestamp(System.currentTimeMillis()));

        return goldPrice;
    }

    private SilverPrice goldDataToSilverPrice(GoldData goldData) throws CustomException{
        SilverPrice silverPrice = new SilverPrice();

        silverPrice.setId(IdUtil.getId());
        Variety variety;
        try{
            variety = this.getVarietyByName(goldData.getVariety());
            if(variety==null){
                throw new CustomException(ErrorCode.ERROR_RECEIVE_AUTD);
            }
        }catch (CustomException e){
            throw e;
        }
        silverPrice.setVarietyId(variety.getId());
        silverPrice.setLatestPrice(new BigDecimal(goldData.getLatestpri()));
        silverPrice.setOpenPrice(new BigDecimal(goldData.getOpenpri()));
        silverPrice.setMaxPrice(new BigDecimal(goldData.getMaxpri()));
        silverPrice.setMinPrice(new BigDecimal(goldData.getMinpri()));
        silverPrice.setYesterdayPrice(new BigDecimal(goldData.getYespri()));
        silverPrice.setTotalVolume(new BigDecimal(goldData.getTotalvol()));
        silverPrice.setTime(goldData.getTime());
        silverPrice.setLatestPriceTime(this.getCurrentTime());
        silverPrice.setCreateDate(new Timestamp(System.currentTimeMillis()));
        silverPrice.setUpdateDate(new Timestamp(System.currentTimeMillis()));

        return silverPrice;
    }

    private Variety getVarietyByName(String varietyType) throws CustomException{
        Variety variety = varietyMapper.findByName(varietyType);
        if(variety==null){
            throw new CustomException(ErrorCode.ERROR_RECEIVE_AUTD);
        }
        return variety;
    }

    private Timestamp getLatestPriceTime(){
        String timeStr = "";

        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        int huor = calendar.get(GregorianCalendar.HOUR_OF_DAY);

        if(huor>=0 && huor<9){
            // 获取前一天14点的最新价
            calendar.set(Calendar.DATE, calendar.get(Calendar.DATE) - 1);
            String format = simpleDateFormat.format(calendar.getTime());
            timeStr = format+" 09:00:00";
        }else if(huor>=9 && huor<14){
            // 获取当天9点的最新价
            String format = simpleDateFormat.format(calendar.getTime());
            timeStr = format+" 09:00:00";
        }else if(huor>=14 && huor<=24){
            // 获取当天14的最新价
            String format = simpleDateFormat.format(calendar.getTime());
            timeStr = format+" 14:00:00";
        }

        return Timestamp.valueOf(timeStr);
    }

    private Timestamp getCurrentTime(){
        String timeStr = "";

        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        String format = simpleDateFormat.format(calendar.getTime());
        int huor = calendar.get(GregorianCalendar.HOUR_OF_DAY);

//        if(huor==8 || huor==9){
        if(huor<14){
            timeStr = format+" 09:00:00";
//        }else if(huor==13 && huor==14){
        }else if(huor>=14){
            timeStr = format+" 14:00:00";
        }

        return Timestamp.valueOf(timeStr);
    }

    @Transactional
    @Override
    public void saveJuheGoldDataByVariety() throws CustomException{
        try{
            JuheResponse<ArrayList<GoldDataMap>> dataByShgold = this.getDataByShgold();
            ArrayList<GoldDataMap> result = dataByShgold.getResult();
            if(result!=null && result.size()>0){
                GoldDataMap goldDataMap = result.get(0);
                if(goldDataMap!=null){
                    if(goldDataMap!=null && goldDataMap.size()>0){
                        GoldData goldData = goldDataMap.get(VarietyType.AuTD);
                        if(goldData!=null){
                            GoldPrice goldPrice = this.goldDataToGoldPrice(goldData);
                            GoldPrice latestPrice = goldPriceMapper.findLatestPrice(goldPrice);
                            if(latestPrice==null){
                                goldPriceMapper.saveGoldPrice(goldPrice);
                            }else{
                                goldPrice.setId(latestPrice.getId());
                                goldPriceMapper.updateGoldPrice(goldPrice);
                            }
                        }
                        goldData = goldDataMap.get(VarietyType.AgTD);
                        if(goldData!=null){
                            SilverPrice silverPrice = this.goldDataToSilverPrice(goldData);
                            SilverPrice latestPrice = silverPriceMapper.findLatestPrice(silverPrice);
                            if(latestPrice==null){
                                silverPriceMapper.saveSilverPrice(silverPrice);
                            }else{
                                silverPrice.setId(latestPrice.getId());
                                silverPriceMapper.updateSilverPrice(silverPrice);
                            }
                        }
                        return ;
                    }
                }
            }
            throw new CustomException(ErrorCode.ERROR_RECEIVE_AUTD);
        }catch (CustomException e){
            throw e;
        }catch (Exception e){
            e.printStackTrace();
            throw new CustomException(ErrorCode.ERROR_RECEIVE_AUTD);
        }
    }

    @Override
    public GoldPrice getLatestGoldTDPrice() throws CustomException{

        try{

            GoldPrice goldPrice = new GoldPrice();
            goldPrice.setVarietyId(this.getVarietyByName(VarietyType.AuTD).getId());
            goldPrice.setLatestPriceTime(this.getLatestPriceTime());
            GoldPrice latestPrice = goldPriceMapper.findLatestPrice(goldPrice);
            if(latestPrice==null){
                this.saveJuheGoldDataByVariety();
                return this.getLatestGoldTDPrice();
//                throw new CustomException(ErrorCode.ERROR_RECEIVE_AUTD);
            }
            return latestPrice;

        }catch (CustomException e){
            throw e;
        }catch (Exception e){
            throw new CustomException(ErrorCode.ERROR_RECEIVE_AUTD);
        }
    }

    @Override
    public SilverPrice getLatestSilvetyTDPrice() throws CustomException{
        try{

            SilverPrice silverPrice = new SilverPrice();
            silverPrice.setVarietyId(this.getVarietyByName(VarietyType.AgTD).getId());
            silverPrice.setLatestPriceTime(this.getLatestPriceTime());
            SilverPrice latestPrice = silverPriceMapper.findLatestPrice(silverPrice);
            if(latestPrice==null){
                this.saveJuheGoldDataByVariety();
                return this.getLatestSilvetyTDPrice();
//                throw new CustomException(ErrorCode.ERROR_RECEIVE_AUTD);
            }
            return latestPrice;

        }catch (CustomException e){
            throw e;
        }catch (Exception e){
            throw new CustomException(ErrorCode.ERROR_RECEIVE_AGTD);
        }
    }

    @Override
    public GsiGoldPrice getLatestGoldTDPriceTotal(GsiGoldPrice gsiPrice) throws CustomException {
        try {
            GoldPrice latestGoldTDPrice = this.getLatestGoldTDPrice();

            gsiPrice.setType(VarietyType.AuTD);

            /**
             * 金价 /g
             */
            BigDecimal priceByG = latestGoldTDPrice.getLatestPrice();
            gsiPrice.setPriceByG(BigDecimalUtil.scaleHalfUp(priceByG));
            /**
             * 零售金价 /g
             */
            BigDecimal retailPriceByG = latestGoldTDPrice.getLatestPrice().add(gsiPrice.getRetailProfitPrice());
            gsiPrice.setRetailPriceByG(BigDecimalUtil.scaleHalfUp(retailPriceByG));
            /**
             * 供货金价 /g
             */
            BigDecimal supplyPriceByG = latestGoldTDPrice.getLatestPrice().add(gsiPrice.getSupplyProfitPrice());
            gsiPrice.setSupplyPriceByG(BigDecimalUtil.scaleHalfUp(supplyPriceByG));
            /**
             * 供货总价
             */
            BigDecimal supplyPrice = priceByG
                    .add(gsiPrice.getSupplyProfitPrice())
                    .multiply(new BigDecimal(String.valueOf(gsiPrice.getQuantity())));
            gsiPrice.setSupplyPriceTotal(BigDecimalUtil.scaleHalfUp(supplyPrice));
            /**
             * 零售总价
             */
            BigDecimal retailPrice = priceByG
                    .add(gsiPrice.getRetailProfitPrice())
                    .multiply( new BigDecimal(String.valueOf(gsiPrice.getQuantity())) );
            gsiPrice.setRetailPriceTotal(BigDecimalUtil.scaleHalfUp(retailPrice));
            /**
             * 银行中收
             */
            BigDecimal backIncome = gsiPrice.getBackIncomePriceByG()
                    .multiply(new BigDecimal(String.valueOf(gsiPrice.getQuantity())));
            gsiPrice.setBackIncome(BigDecimalUtil.scaleHalfUp(backIncome));

            return gsiPrice;

        }catch (CustomException e){
            throw e;
        }catch (Exception e){
            throw new CustomException(ErrorCode.ERROR_RECEIVE_AGTD);
        }
    }

    @Override
    public GsiSilverPrice getLatestSilvetyTDPriceTotal(GsiSilverPrice gsiPrice) throws CustomException {
        try {
            SilverPrice latestSilvetyTDPrice = this.getLatestSilvetyTDPrice();

            gsiPrice.setType(VarietyType.AgTD);

            /**
             * 实时金价*零售价比例 /g
             */
            BigDecimal priceByG = latestSilvetyTDPrice.getLatestPriceG();
            gsiPrice.setPriceByG(BigDecimalUtil.scaleHalfUp(priceByG));
            /**
             * 零售金价 /g
             */
            BigDecimal retailPriceByG = latestSilvetyTDPrice.getLatestPriceG().multiply(gsiPrice.getRetailPriceProportion());
            gsiPrice.setRetailPriceByG(BigDecimalUtil.scaleHalfUp(retailPriceByG));
            /**
             * 供货金价 /g
             */
            BigDecimal supplyPriceByG = latestSilvetyTDPrice.getLatestPriceG().multiply(gsiPrice.getSupplyPriceProportion());
            gsiPrice.setSupplyPriceByG(BigDecimalUtil.scaleHalfUp(supplyPriceByG));
            /**
             * 供货总价
             */
            BigDecimal supplyPrice = priceByG
                    .multiply( new BigDecimal(String.valueOf(gsiPrice.getQuantity())) )
                    .multiply(new BigDecimal(String.valueOf(gsiPrice.getSupplyPriceProportion())));
            gsiPrice.setSupplyPriceTotal(BigDecimalUtil.scaleHalfUp(supplyPrice));
            /**
             * 零售总价
             */
            BigDecimal retailPrice = priceByG
                    .multiply(new BigDecimal(String.valueOf(gsiPrice.getQuantity())))
                    .multiply( new BigDecimal(String.valueOf(gsiPrice.getRetailPriceProportion())) );
            gsiPrice.setRetailPriceTotal(BigDecimalUtil.scaleHalfUp(retailPrice));
            /**
             * 银行中收
             */
            BigDecimal backIncome = priceByG
                    .multiply( new BigDecimal(String.valueOf(gsiPrice.getBackIncomeProportion())) )
                    .multiply(new BigDecimal(String.valueOf(gsiPrice.getQuantity())));
            gsiPrice.setBackIncome(BigDecimalUtil.scaleHalfUp(backIncome));


            return gsiPrice;


        }catch (CustomException e){
            throw e;
        }catch (Exception e){
            throw new CustomException(ErrorCode.ERROR_RECEIVE_AUTD);
        }
    }


}
